home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 58189 / 58189.xpi / modules / DataService.jsm < prev    next >
Text File  |  2010-01-06  |  11KB  |  321 lines

  1. /*
  2.  * The DataService is the Policy Information Point for requests. All the information
  3.  * is collected here. This information can be used to make decisions about the
  4.  * accpetance of certain requests.
  5.  */
  6.  
  7. var EXPORTED_SYMBOLS = [ ];
  8. Components.utils.import("resource://csfiremodules/CsFireCommon.jsm");
  9.  
  10. CsFire.DataService = new function() {
  11.     // Define the information stores
  12.     this.userRequests = new Array();
  13.     this.loadRequests = new Array();
  14.     this.httpRequests = new Array();
  15.     
  16.     this.lastCheck = 0;
  17.     this.checkingTreshold = 5000;
  18.     this.removalTreshold = 5000;
  19. }
  20.  
  21. /*
  22.  * Registers user interaction for a certain destination URI. The URI of the
  23.  * originating page is also registered.
  24.  */
  25. CsFire.DataService.registerUserInteraction = function(dst, src) {
  26.     /*
  27.      * Register data for later use. Since we only have a string URI, we'll
  28.      * use that to store the request information.
  29.      */
  30.      var userData = {"dest": dst, "orig": src, "timestamp": new Date().getTime()};
  31.      
  32.     CsFire.Logger.debug("Registering user interaction: " + dst);
  33.     this.userRequests[dst] = userData;
  34. }
  35.  
  36. /*
  37.  * Registers a load request for a certain destination. The expected content type,
  38.  * originating page and context (DOM element) are also registered.
  39.  */
  40. CsFire.DataService.registerLoadRequest = function(dstUri, srcUri, contentType, context) {
  41.     var stringUri = dstUri.prePath + dstUri.path;
  42.     
  43.     /* 
  44.      * The browser has the tendency to submit load requests twice, so only register
  45.      * them the first time. The second time, we bail out.
  46.      *
  47.      * Caution: when using the "back"-button and then clicking a new link, the same Uri-object
  48.      * is used. Therefore, also check the string representation of the URIs to make sure
  49.      * we're dealing with the same request
  50.      */
  51.     if(this.loadRequests[stringUri] != null) {
  52.         return;
  53.     }
  54.         
  55.     // Split the destination URI and collect all load data
  56.     var dst = CsFire.HttpUtils.splitUri(dstUri);
  57.     var loadData = {"dst_uri":            dstUri,
  58.                     "dst_scheme":        dst.scheme,
  59.                     "dst_host":            dst.host,
  60.                     "dst_port":            dst.port,
  61.                     "dst_path":            dst.path,
  62.                     "dst_item":            dst.item,
  63.                     "params":            dst.params,
  64.                     "referrer_scheme":    null,
  65.                     "referrer_host":    null,
  66.                     "referrer_port":    null,
  67.                     "referrer_uri":        null,
  68.                     "type":                contentType,
  69.                     "node":                null,
  70.                     "timestamp":         new Date().getTime()};
  71.     
  72.     /*
  73.      * Try to set the referrer. Some sites do dirty things with JS, which causes 
  74.      * mozilla to use "moz-nullprincipal" as a scheme
  75.      */
  76.     if(srcUri.scheme != "moz-nullprincipal") {
  77.         loadData.referrer_uri = srcUri;
  78.         loadData.referrer_scheme = srcUri.scheme;
  79.         loadData.referrer_host = srcUri.host;
  80.         loadData.referrer_port = srcUri.port;
  81.     }
  82.     
  83.     // Check the source DOM element of the request
  84.     try {
  85.         context.QueryInterface(Components.interfaces.nsIDOMNode);
  86.         loadData.node = context.nodeName;
  87.     }
  88.     catch(e) {}
  89.                 
  90.     /*
  91.      * Register data for later use. We have an URI object, which will be the same
  92.      * object with the HTTP request, so we can use that to store the load data.
  93.      */
  94.     CsFire.Logger.debug("Registering load data: " + stringUri);
  95.     this.loadRequests[stringUri] = loadData;
  96. }
  97.  
  98. /*
  99.  * This method registers all the necessary information about the HTTP request.
  100.  * All this information is available in the httpChannel object.
  101.  *
  102.  * Note: we can not check for auth headers here, since Firefox has not yet
  103.  * added cached credentials at this point.
  104.  */
  105. CsFire.DataService.registerHttpRequest = function(httpChannel) {
  106.     var stringUri = httpChannel.URI.prePath + httpChannel.URI.path;
  107.     
  108.     // Split the destination URI and collect all http data
  109.     var dst = CsFire.HttpUtils.splitUri(httpChannel.URI);    
  110.     var httpData = {"method":             httpChannel.requestMethod,
  111.                     "dst_scheme":        dst.scheme,
  112.                     "dst_host":            dst.host,
  113.                     "dst_port":            dst.port,
  114.                     "dst_path":            dst.path,
  115.                     "dst_item":            dst.item,
  116.                     "dst_uri":            httpChannel.URI,
  117.                     "params":            dst.params,
  118.                     "referrer_scheme":    null,
  119.                     "referrer_host":    null,
  120.                     "referrer_port":    null,
  121.                     "referrer_uri":        null,
  122.                     "redirect":            false,
  123.                     "cookies":            [],
  124.                     "timestamp":         new Date().getTime()};
  125.  
  126.  
  127.  
  128.     // Check referrer
  129.     if(httpChannel.referrer != null) {
  130.         var uri = CsFire.HttpUtils.splitUri(httpChannel.referrer);
  131.         httpData.referrer_uri = httpChannel.referrer;
  132.         httpData.referrer_scheme = uri.scheme;
  133.         httpData.referrer_host = uri.host;
  134.         httpData.referrer_port = uri.port;
  135.     }
  136.     
  137.  
  138.     // Check for redirects
  139.     if(httpChannel.originalURI != null && httpChannel.originalURI != httpChannel.URI) {
  140.         /*
  141.          * Redirects by means of the "Refresh" header or the HTML-tag pass through the "shouldLoad" method
  142.          * so they will be handled automatically. Redirects using the "Location" header don't, which is why we
  143.          * extract the necessary information here.
  144.          */
  145.          
  146.         var httpOrig = CsFire.HttpUtils.splitUri(httpChannel.originalURI);
  147.         httpData.redirect = true;
  148.         httpData.referrer_uri = httpChannel.originalURI;
  149.         httpData.referrer_scheme = httpOrig.scheme;
  150.         httpData.referrer_host = httpOrig.host;
  151.         httpData.referrer_port = httpOrig.port;
  152.         
  153.         CsFire.Logger.debug("Detected redirect: " + httpChannel.originalURI.prePath + " ==> " + httpChannel.URI.prePath);
  154.     }
  155.  
  156.     //Check for cookies and extract key names
  157.     httpData.cookies = CsFire.HttpUtils.extractCookies(httpChannel);
  158.     
  159.     /*
  160.      * Register data for later use. We have an URI object, which is the same
  161.      * object as the load request, so we can use that to store the http data.
  162.      */ 
  163.     CsFire.Logger.debug("Registering HTTP data: " + stringUri);
  164.     this.httpRequests[stringUri] = httpData;
  165. }
  166.  
  167. /*
  168.  * Retrieves the data associated with this request and removes it from the stores.
  169.  */
  170. CsFire.DataService.getAndRemoveRequestData = function(uri) {
  171.     var stringUri = uri.prePath + uri.path;
  172.     var data = { "user": null, "load": null, "http": null };
  173.     
  174.     // Collect the user data (string based URI)
  175.     data.user = this.userRequests[stringUri];
  176.     delete this.userRequests[stringUri];
  177.     
  178.     // Collect the load data (URI)
  179.     data.load = this.loadRequests[stringUri];
  180.     delete this.loadRequests[stringUri];
  181.     
  182.     // Collect the HTTP data (URI)
  183.     data.http = this.httpRequests[stringUri];
  184.     delete this.httpRequests[stringUri];
  185.     
  186.     // Clean data stores
  187.     this._cleanDataStores();
  188.     
  189.     // Check if we have found any info
  190.     if(data.user == null && data.load == null && data.http == null) {
  191.         /* 
  192.          * Theoretically, this can occur if two simultaneous requests are
  193.          * processed at exactly the same time ...
  194.          * Practically: does not sem to occur
  195.          */
  196.         data = null;
  197.     }
  198.     
  199.     return this._combineData(data);
  200. }
  201.  
  202. /*
  203.  * Checks the internal datastores for stale requests that can be removed.
  204.  * A timestamp is used to determine this (Configurable using variables in the
  205.  * constructor).
  206.  */
  207. CsFire.DataService._cleanDataStores = function() {
  208.     var time = new Date().getTime();
  209.     if(time - this.lastCheck > this.checkingTreshold) {
  210.         this.lastCheck = time;
  211.         var maxAge = time - this.removalTreshold;
  212.         this._cleanDataStore(this.userRequests, maxAge);
  213.         this._cleanDataStore(this.loadRequests, maxAge);
  214.         this._cleanDataStore(this.httpRequests, maxAge);
  215.     }
  216. }
  217.  
  218. /*
  219.  * Checks the entries in the provided data store against the given max age. If
  220.  * an entry is too old, it is removed from the store.
  221.  */
  222. CsFire.DataService._cleanDataStore = function(store, maxAge) {
  223.     for(var index in store) {
  224.         var o = store[index];
  225.         if(o != null && o.timestamp != null && o.timestamp < maxAge) {
  226.             delete store[index];
  227.         }
  228.     }
  229. }
  230.  
  231. /*
  232.  * This function combines data from all sources in to a single object, which can
  233.  * easily be used to make policy decisions
  234.  */
  235. CsFire.DataService._combineData = function(data) {
  236.     // Extract the different parts
  237.     var user = data.user;
  238.     var load = data.load;
  239.     var http = data.http;
  240.     
  241.     // Define the combined data object
  242.     var comb = {"dst_scheme": null,
  243.                 "dst_host": null,
  244.                 "dst_port": null,
  245.                 "dst_uri": null,
  246.                 "referrer_scheme": null,
  247.                 "referrer_host": null,
  248.                 "referrer_port": null,
  249.                 "referrer_uri": null,
  250.                 "dst_path": null,
  251.                 "dst_item": null,
  252.                 "params": null,
  253.                 "type": null,
  254.                 "node": null,
  255.                 "method": null,
  256.                 "redirect": false,
  257.                 "cookies": null,
  258.                 "user_initiated": false };
  259.     
  260.     // Extract common data between load and http
  261.     var extractedCommon = false;
  262.     if(load != null && http != null) {
  263.         extractedCommon = true;
  264.         
  265.         // Extract common data
  266.         load.dst_scheme == null ? comb.dst_scheme = http.dst_scheme : comb.dst_scheme = load.dst_scheme;
  267.         load.dst_host == null ? comb.dst_host = http.dst_host : comb.dst_host = load.dst_host;
  268.         load.dst_port == null ? comb.dst_port = http.dst_port : comb.dst_port = load.dst_port;
  269.         load.dst_item == null ? comb.dst_item = http.dst_item : comb.dst_item = load.dst_item;
  270.         load.dst_uri == null ? comb.dst_uri = http.dst_uri : comb.dst_uri = load.dst_uri;
  271.         load.dst_path == null ? comb.dst_path = http.dst_path : comb.dst_path = load.dst_path;
  272.         load.params == null ? comb.params = http.params : comb.params = load.params;
  273.         load.referrer_scheme == null ? comb.referrer_scheme = http.referrer_scheme : comb.referrer_scheme = load.referrer_scheme;
  274.         load.referrer_host == null ? comb.referrer_host = http.referrer_host : comb.referrer_host = load.referrer_host;
  275.         load.referrer_port == null ? comb.referrer_port = http.referrer_port : comb.referrer_port = load.referrer_port;
  276.         load.referrer_uri == null ? comb.referrer_uri = http.referrer_uri : comb.referrer_uri = load.referrer_uri;
  277.     }
  278.     
  279.     // Extract user specific data
  280.     if(user != null) {
  281.         comb.user_initiated = true;
  282.     }
  283.     
  284.     // Extract load specific data
  285.     if(load != null) {
  286.         comb.type = load.type;
  287.         comb.node = load.node;
  288.         if(!extractedCommon) {
  289.             comb.dst_scheme = load.dst_scheme;
  290.             comb.dst_host = load.dst_host;
  291.             comb.dst_port = load.dst_port;
  292.             comb.referrer_scheme = load.referrer_scheme;
  293.             comb.referrer_host = load.referrer_host;
  294.             comb.referrer_port = load.referrer_port;
  295.             comb.referrer_uri = load.referrer_uri;
  296.             comb.dst_item = load.dst_item;
  297.             comb.params = load.params;
  298.         }
  299.     }
  300.     
  301.     // Extract http specific data
  302.     if(http != null) {
  303.         comb.method = http.method;
  304.         comb.redirect = http.redirect;
  305.         comb.cookies = http.cookies;
  306.         if(!extractedCommon) {
  307.             comb.dst_scheme = http.dst_scheme;
  308.             comb.dst_host = http.dst_host;
  309.             comb.dst_port = http.dst_port;
  310.             comb.referrer_scheme = http.referrer_scheme;
  311.             comb.referrer_host = http.referrer_host;
  312.             comb.referrer_port = http.referrer_port;
  313.             comb.referrer_uri = http.referrer_uri;
  314.             comb.dst_item = http.dst_item;
  315.             comb.params = http.params;
  316.         }
  317.     }
  318.     
  319.     return comb;
  320. }
  321.